package handlers

import (
	"net/http"
	"strconv"
	"task_queue/internal/models"   // 导入 models 包
	"task_queue/internal/response" // 导入 response 包

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/jinzhu/copier" // <-- 导入 copier 库
	"gorm.io/gorm"
)

type AuthKeyHandler struct {
	DB *gorm.DB
}

func NewAuthKeyHandler(db *gorm.DB) *AuthKeyHandler {
	return &AuthKeyHandler{
		DB: db,
	}
}

// CreateAuthKey 创建新的认证密钥
func (h *AuthKeyHandler) CreateAuthKey(c *gin.Context) {
	var req models.ReqAuthKey // 假设你有一个用于请求绑定的 ReqAuthKey 结构体
	if err := c.ShouldBindJSON(&req); err != nil {
		response.Fail(c, http.StatusBadRequest, "无效的请求数据: "+err.Error())
		return
	}

	var authModel models.AuthKey
	if err := copier.Copy(&authModel, &req); err != nil {
		response.Fail(c, http.StatusInternalServerError, "复制请求数据失败: "+err.Error())
		return
	}

	authModel.AuthKeyValue = "api-key-" + uuid.New().String()

	// 创建记录
	result := h.DB.Create(&authModel)
	if result.Error != nil {
		response.Fail(c, http.StatusInternalServerError, "创建认证密钥失败: "+result.Error.Error())
		return
	}

	response.Success(c, authModel)
}

// GetAuthKey 获取单个认证密钥信息
func (h *AuthKeyHandler) GetAuthKey(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32) // AuthKey 的 ID 是 uint
	if err != nil {
		response.Fail(c, http.StatusBadRequest, "无效的 ID 格式")
		return
	}

	var authKey models.AuthKey
	// 根据 ID 查询
	result := h.DB.First(&authKey, uint(id)) // GORM 需要 uint 类型

	// 处理查询结果
	if result.Error != nil {
		if result.Error == gorm.ErrRecordNotFound {
			response.Fail(c, http.StatusNotFound, "认证密钥未找到")
		} else {
			response.Fail(c, http.StatusInternalServerError, "查询认证密钥失败: "+result.Error.Error())
		}
		return
	}

	response.Success(c, authKey)
}

// ListAuthKeys 获取认证密钥列表（支持分页）
func (h *AuthKeyHandler) ListAuthKeys(c *gin.Context) {
	var authKeys []models.AuthKey
	// 获取分页参数
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))

	if page < 1 {
		page = 1
	}
	if pageSize < 1 {
		pageSize = 10
	}
	offset := (page - 1) * pageSize

	// 查询分页数据
	result := h.DB.Offset(offset).Limit(pageSize).Find(&authKeys)
	if result.Error != nil {
		response.Fail(c, http.StatusInternalServerError, "查询认证密钥列表失败: "+result.Error.Error())
		return
	}

	// 查询总数（用于分页）
	var total int64
	countResult := h.DB.Model(&models.AuthKey{}).Count(&total)
	if countResult.Error != nil {
		response.Fail(c, http.StatusInternalServerError, "查询总数失败: "+countResult.Error.Error())
		return
	}

	// 返回分页结果
	response.Success(c, gin.H{
		"items":    authKeys,
		"total":    total,
		"page":     page,
		"pageSize": pageSize,
	})
}

// UpdateAuthKey 更新认证密钥信息
func (h *AuthKeyHandler) UpdateAuthKey(c *gin.Context) {
	// 从 URL 参数获取 ID
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.Fail(c, http.StatusBadRequest, "无效的 ID 格式")
		return
	}

	// 先查找记录是否存在
	var existingAuthKey models.AuthKey
	findResult := h.DB.First(&existingAuthKey, uint(id))
	if findResult.Error != nil {
		if findResult.Error == gorm.ErrRecordNotFound {
			response.Fail(c, http.StatusNotFound, "认证密钥未找到")
		} else {
			response.Fail(c, http.StatusInternalServerError, "查询认证密钥失败: "+findResult.Error.Error())
		}
		return
	}

	// 绑定 JSON 请求体到 ReqAuthKey 结构体
	var req models.ReqAuthKey
	if err := c.ShouldBindJSON(&req); err != nil {
		// 修正错误码
		response.Fail(c, http.StatusBadRequest, "无效的请求数据: "+err.Error())
		return
	}
	existingAuthKey.AllowedPullTopics = req.AllowedPullTopics
	existingAuthKey.AllowedPushTopics = req.AllowedPushTopics
	existingAuthKey.CanPull = req.CanPull
	existingAuthKey.CanPush = req.CanPush
	existingAuthKey.Description = req.Description
	existingAuthKey.IsActive = req.IsActive

	existingAuthKey.Description = req.Description
	updateResult := h.DB.Model(&existingAuthKey).Save(existingAuthKey) // 直接使用 req 更新匹配的字段

	if updateResult.Error != nil {
		response.Fail(c, http.StatusInternalServerError, "更新认证密钥失败: "+updateResult.Error.Error())
		return
	}

	// 返回更新后的记录（existingAuthKey 已经被 Updates 更新了）
	response.Success(c, existingAuthKey)
}

// DeleteAuthKey 删除认证密钥并返回被删除的对象
func (h *AuthKeyHandler) DeleteAuthKey(c *gin.Context) {
	// 从 URL 参数获取 ID
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.Fail(c, http.StatusBadRequest, "无效的 ID 格式")
		return
	}

	// 1. 先查找要删除的记录
	var authKeyToDelete models.AuthKey
	findResult := h.DB.First(&authKeyToDelete, uint(id))
	if findResult.Error != nil {
		if findResult.Error == gorm.ErrRecordNotFound {
			response.Fail(c, http.StatusNotFound, "认证密钥未找到")
		} else {
			response.Fail(c, http.StatusInternalServerError, "查询认证密钥失败: "+findResult.Error.Error())
		}
		return
	}

	// 2. 执行删除操作
	// GORM 默认执行软删除（如果模型包含 gorm.DeletedAt）
	// 如果你的 gormModel 包含 DeletedAt，这里会是软删除
	// 如果想强制硬删除，可以使用 Unscoped()
	deleteResult := h.DB.Delete(&models.AuthKey{}, uint(id)) // 仍然需要指定模型和 ID

	if deleteResult.Error != nil {
		response.Fail(c, http.StatusInternalServerError, "删除认证密钥失败: "+deleteResult.Error.Error())
		return
	}

	// 检查是否真的有记录被删除 (虽然理论上前面已经查到了)
	if deleteResult.RowsAffected == 0 {
		// 这种情况理论上不应该发生，因为前面已经 First 成功了
		response.Fail(c, http.StatusNotFound, "认证密钥未找到或删除失败")
		return
	}

	// 3. 返回之前查找到的被删除对象
	response.Success(c, authKeyToDelete)
}
